package com.ogawa.base.utils;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Application;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.os.StatFs;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.method.HideReturnsTransformationMethod;
import android.text.method.PasswordTransformationMethod;
import android.util.Base64;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.google.gson.Gson;
import com.ogawa.base.base.BaseApp;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * APP 工具类
 * Created by HourGlassRemember on 2018/10/25.
 */
public class AppUtil {

    private static final String TAG = "AppUtil";
    private static final int MIN_CLICK_DELAY_TIME = 500;// 两次点击按钮之间的点击间隔不能少于 1000 毫秒
    private static final String DEFAULT_MAC = "02:00:00:00:00:02";

    private static long lastClickTime;
    private static Application mContext = BaseApp.appContext;


    /**
     * 是否是正常点击，
     * 两次点击之间时间间隔少于 1000 毫秒就算为过快点击，此时判断为一次点击事件
     *
     * @return
     */
    public static boolean isNormalClick() {
        boolean flag = false;
        long currentClickTime = System.currentTimeMillis();
        if ((currentClickTime - lastClickTime) >= MIN_CLICK_DELAY_TIME) {
            flag = true;
            lastClickTime = currentClickTime;
        }
        return flag;
    }

    /**
     * 是否是正常点击，
     * 两次点击之间时间间隔少于 time 毫秒就算为过快点击，此时判断为一次点击事件
     *
     * @return
     * @time 自定义两次有效点击的间隔
     */
    public static boolean isNormalClick(long time) {
        boolean flag = false;
        long currentClickTime = System.currentTimeMillis();
        if ((currentClickTime - lastClickTime) >= time) {
            flag = true;
            lastClickTime = currentClickTime;
        }

        return flag;
    }


    /**
     * 设置文字左方的图片资源
     *
     * @param resources
     * @param textView
     * @param drawableId 图片 ID
     */
    public static void setTextDrawableLeft(Resources resources, TextView textView, int drawableId) {
        textView.setCompoundDrawablesWithIntrinsicBounds(-1 == drawableId ? null : resources.getDrawable(drawableId), null, null, null);
    }

    /**
     * 设置文字右方的图片资源
     *
     * @param resources
     * @param textView
     * @param drawableId 图片 ID
     */
    public static void setTextDrawableRight(Resources resources, TextView textView, int drawableId) {
        textView.setCompoundDrawablesWithIntrinsicBounds(null, null, -1 == drawableId ? null : resources.getDrawable(drawableId), null);
    }

    /**
     * 设置文字上方的图片资源
     *
     * @param resources
     * @param textView
     * @param drawableId 图片 ID
     */
    public static void setTextDrawableTop(Resources resources, TextView textView, int drawableId) {
        textView.setCompoundDrawablesWithIntrinsicBounds(null, -1 == drawableId ? null : resources.getDrawable(drawableId), null, null);
    }

    /**
     * 设置文字下方的图片资源TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
     *
     * @param resources
     * @param textView
     * @param drawableId 图片 ID
     */
    public static void setTextDrawableBottom(Resources resources, TextView textView, int drawableId) {
        textView.setCompoundDrawablesWithIntrinsicBounds(null, null, null, -1 == drawableId ? null : resources.getDrawable(drawableId));
    }

    /**
     * 密码明文与密文的切换
     *
     * @param isBrowse  是否浏览密码
     * @param imageView 浏览控件
     * @param editText  输入文本控件
     */
    public static void switchPasswordState(boolean isBrowse, ImageView imageView, EditText editText) {
        imageView.setSelected(isBrowse);
        editText.setTransformationMethod(isBrowse ? HideReturnsTransformationMethod.getInstance() : PasswordTransformationMethod.getInstance());
        editText.setSelection(editText.getText().length());// 设置光标显示在最后面
    }

    /**
     * 每次操作按键音的时候都要先去判断下是否有 WRITE_SETTINGS 的权限
     *
     * @param context 上下文
     * @return
     */
    public static boolean askWriteSettingPermission(Context context) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
            if (!Settings.System.canWrite(context)) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + context.getPackageName()));
                context.startActivity(intent);
            } else {
                return true;
            }
        } else {
            return true;
        }
        return false;
    }

    /**
     * 根据 isOpen 值打开或关闭按键音
     *
     * @param context 上下文
     * @param isOpen  是否打开按键音
     */
    public static void openSystemVoice(Context context, boolean isOpen) {
        AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        if (null != audioManager) {
            if (isOpen) {// 打开按键音
                audioManager.loadSoundEffects();
                Settings.System.putInt(context.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 1);
            } else {// 关闭按键音
                audioManager.unloadSoundEffects();
                Settings.System.putInt(context.getContentResolver(), Settings.System.SOUND_EFFECTS_ENABLED, 0);
            }
        }
    }

    /**
     * 判断一个字符串是否为空
     *
     * @param string
     * @return
     */
    public static boolean isEmpty(String string) {
        return !(null != string && !string.equals(""));
    }

    /**
     * 获取 APP 版本名称
     *
     * @return
     */
    public static String getVersionName() {
        return getPackageInfo(mContext).versionName;
    }

    /**
     * 获取 APP 版本号
     *
     * @param context 上下文
     * @return
     */
    public static int getVersionCode(Context context) {
//        return getPackageInfo(context).versionCode;
        int versionCode = 0;
        try {
            versionCode = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return versionCode;
    }

    /**
     * 根据Uri获取图片绝对路径，解决Android4.4以上版本Uri转换
     *
     * @param imageUri
     * @author yaoxing
     * @date 2014-10-12
     */
    @TargetApi(19)
    public static String getImageAbsolutePath(Activity context, Uri imageUri) {
        if (context == null || imageUri == null)
            return null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) {
            if (isExternalStorageDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }
            } else if (isDownloadsDocument(imageUri)) {
                String id = DocumentsContract.getDocumentId(imageUri);
                Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                return getDataColumn(context, contentUri, null, null);
            } else if (isMediaDocument(imageUri)) {
                String docId = DocumentsContract.getDocumentId(imageUri);
                String[] split = docId.split(":");
                String type = split[0];
                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }
                String selection = MediaStore.Images.Media._ID + "=?";
                String[] selectionArgs = new String[]{split[1]};
                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        } // MediaStore (and general)
        else if ("content".equalsIgnoreCase(imageUri.getScheme())) {
            // Return the remote address
            if (isGooglePhotosUri(imageUri))
                return imageUri.getLastPathSegment();
            return getDataColumn(context, imageUri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(imageUri.getScheme())) {
            return imageUri.getPath();
        }
        return null;
    }

    private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        String column = MediaStore.Images.Media.DATA;
        String[] projection = {column};
        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                int index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     */
    private static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    private static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    private static PackageInfo getPackageInfo(Context context) {
        try {
            return context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_CONFIGURATIONS);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取 androidID
     *
     * @param context 上下文
     * @return
     */
    @SuppressLint("HardwareIds")
    public static String getAndroidID(Context context) {
        return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    /**
     * 获取当前手机系统版本号
     *
     * @return 系统版本号
     */
    public static String getSystemVersion() {
        return android.os.Build.VERSION.RELEASE;
    }

    /**
     * 获取手机 MAC 地址
     *
     * @return
     */
    public static String getMacAddress() {
        String macAddress;
        try {
            NetworkInterface networkInterface = NetworkInterface.getByName("eth1");
            if (null == networkInterface) {
                networkInterface = NetworkInterface.getByName("wlan0");
            }
            if (null == networkInterface) {
                return DEFAULT_MAC;
            }
            StringBuilder stringBuilder = new StringBuilder();
            byte[] addressList = networkInterface.getHardwareAddress();
            for (byte address : addressList) {
                stringBuilder.append(String.format("%02X:", address));
            }
            if (stringBuilder.length() > 0) {
                stringBuilder.deleteCharAt(stringBuilder.length() - 1);// 去掉最后一个冒号(:)
            }
            macAddress = stringBuilder.toString();
        } catch (SocketException e) {
            e.printStackTrace();
            return DEFAULT_MAC;
        }
        return macAddress;
    }

    /**
     * 记录可用空间
     *
     * @param context 上下文
     * @return
     */
    public static long recordAvailableSpace(Context context) {
        if (hasSdcard()) {// 有 SD 卡
            String filePath = "/sdcard";
            StatFs stat = new StatFs(filePath);
            return stat.getAvailableBlocks() * stat.getBlockSize();
        }
        return -1;
    }

    /**
     * 获取注册类型
     *
     * @param content
     * @return
     */
    public static String getRegisterType(String content) {
        return content.contains("@") ? "email" : "mobile";
    }

    /**
     * 获取验证码类型
     * 返回1为短信验证码，2为邮箱验证码
     *
     * @param content
     * @return
     */
    public static int getCodeType(String content) {
        return content.contains("@") ? 1 : 2;
    }

    /**
     * 获取登录类型
     * 返回3为邮箱登录，2为手机号码登录
     *
     * @param content
     * @return
     */
    public static int getLoginType(String content) {
        return content.contains("@") ? 3 : 2;
    }

    /**
     * 检查设备是否存在 SDCard 的工具方法
     */
    public static boolean hasSdcard() {
        return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
    }

    /**
     * 强制隐藏键盘
     *
     * @param context 上下文
     * @param iBinder
     */
    public static void hideKeyboard(Context context, IBinder iBinder) {
        InputMethodManager inputMethodManager = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(iBinder, 0);// 强制隐藏键盘
    }

    /**
     * 隐藏键盘
     *
     * @param context 上下文
     */
    public static void hideKeyboard(Context context, View v) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0); //强制隐藏键盘
    }

    /**
     * 检查系统 GPS 是否打开
     *
     * @param context 上下文
     * @return
     */
    public static boolean checkGPSIsOpen(Context context) {
        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        if (null == locationManager) {
            return false;
        }
        return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    }

    public static String getTopActivity(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        if (null != manager) {
            List<ActivityManager.RunningTaskInfo> runningTaskInfos = manager.getRunningTasks(1);
            if (null != runningTaskInfos && runningTaskInfos.size() > 0) {
                return runningTaskInfos.get(0).topActivity.getClassName();
            }
        }
        return "";
    }

    /**
     * 验证邮箱格式
     *
     * @param email
     * @return
     */
    public static boolean emailFormat(String email) {
        String regex = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*\\.[a-zA-Z0-9]{2,6}$";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }

    /**
     * 获取状态栏高度
     */
    public static int getStatusHeight() {
        int statusBarHeight1 = -1;
        //获取status_bar_height资源的ID
        int resourceId = mContext.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            //根据资源ID获取响应的尺寸值
            statusBarHeight1 = mContext.getResources().getDimensionPixelSize(resourceId);
        }
        return statusBarHeight1;
    }

    /**
     * 检查是否存在虚拟按键栏
     *
     * @param context
     * @return
     */
    public static boolean hasNavBar(Context context) {
        Resources res = context.getResources();
        int resourceId = res.getIdentifier("config_showNavigationBar", "bool", "android");
        if (resourceId != 0) {
            boolean hasNav = res.getBoolean(resourceId);
            // check override flag
            String sNavBarOverride = getNavBarOverride();
            if ("1".equals(sNavBarOverride)) {
                hasNav = false;
            } else if ("0".equals(sNavBarOverride)) {
                hasNav = true;
            }
            return hasNav;
        } else { // fallback
            return !ViewConfiguration.get(context).hasPermanentMenuKey();
        }
    }

    /**
     * 判断虚拟按键栏是否重写
     *
     * @return
     */
    private static String getNavBarOverride() {
        String sNavBarOverride = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            try {
                Class c = Class.forName("android.os.SystemProperties");
                Method m = c.getDeclaredMethod("get", String.class);
                m.setAccessible(true);
                sNavBarOverride = (String) m.invoke(null, "qemu.hw.mainkeys");
            } catch (Throwable e) {
            }
        }
        return sNavBarOverride;
    }

    /**
     * Object 转成 Json 字符串
     **/
    public static <T> String objectToJson(T object) {
        if (object == null) {
            return "";
        }
        Gson gson = new Gson();
        return gson.toJson(object);
    }

    /**
     * Json 字符串 转成Object
     **/
    public static <T> T jsonToObject(String json, Class<T> cls) {
        if (TextUtils.isEmpty(json)) {
            return null;
        }
        Gson gson = new Gson();
        T object = gson.fromJson(json, cls);
        return object;
    }


    /*
    数据转成Base64编码的字符串
     */
    public static String imageToBase64(byte[] data) {
        String result = null;
        try {
            result = Base64.encodeToString(data, Base64.NO_WRAP);// 用默认的编码格式进行编码
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 将图片转换成Base64编码的字符串
     *
     * @param path
     * @return
     */
    public static String imageToBase64(String path) {
        if (TextUtils.isEmpty(path)) {
            return null;
        }
        InputStream inputStream = null;
        byte[] data = null;
        String result = null;
        try {
            inputStream = new FileInputStream(path);
            data = new byte[inputStream.available()];// 创建一个字符流大小的数组
            inputStream.read(data);// 写入数组
            result = Base64.encodeToString(data, Base64.NO_WRAP);// 用默认的编码格式进行编码
        } catch (Exception e) {
            e.printStackTrace();
            result = "";
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * 根据资源名称获取资源ID
     * @param resName
     * @param dir
     * @param packName
     * @return
     */
    public static int getResourceIdByName(Resources res,String resName, String dir, String packName) {
        return res.getIdentifier(resName, dir, packName);
    }
}
